﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Runtime.InteropServices;
using System.Windows.Forms.Calendar;

namespace Helix_Network_Supervisor_3
{
    class FileManipulator
    {
        #region Fields

        private VixenXMLParser vixenParser = new VixenXMLParser();
        private ApplicationSettings settings; //Application Settings
        private string profilePath = "";
        public string channelMapPath = "";

        #endregion Fields

        #region External Methods

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]

        public static extern int GetShortPathName(

                 [MarshalAs(UnmanagedType.LPTStr)]

                   string path,

                 [MarshalAs(UnmanagedType.LPTStr)]

                   StringBuilder shortPath,

                 int shortPathLength

                 );
        #endregion External Methods

        #region Ctor

        public FileManipulator()
        {
            settings = new ApplicationSettings();
            profilePath = settings.vixenV2ProfilePath;
        }

        #endregion Ctor

        #region Show Save/Open

        public void SaveShow(ListView.ListViewItemCollection Show, string destinationFile)
        {
            /*
             *Save a Show file as an XML file.
             *The show data is in a ListViewItemCollection with the following order:
             *Item[0]=Sequence Name
             *Item[1]=Sequence Path
             *Item[2]=Song Title
             *Item[3]=Song Path
             *Item[4]=Time in seconds
             *Item[5]=Size in MBytes
             *Item[6]=Size in Bytes
             *Item[7]=Number of Channels
             */

            XmlTextWriter writer = new XmlTextWriter(destinationFile, null);

            writer.Formatting = Formatting.Indented;

            //Write the header
            writer.WriteStartDocument(false);

            //Root element
            writer.WriteStartElement("Show");

            //Write each sequence to the file
            foreach (ListViewItem Sequence in Show)
            {
                writer.WriteStartElement("Sequence");

                if (Sequence.SubItems[0].Text != "Pause")
                {
                    //Write a standard sequence to the file
                    writer.WriteElementString("SequenceName", Sequence.SubItems[0].Text);
                    writer.WriteElementString("SequencePath", Sequence.SubItems[1].Text);
                    writer.WriteElementString("SongTitle", Sequence.SubItems[2].Text);
                    writer.WriteElementString("SongPath", Sequence.SubItems[3].Text);
                    writer.WriteElementString("TimeInSeconds", Sequence.SubItems[4].Text);
                    writer.WriteElementString("SizeInMBytes", Sequence.SubItems[5].Text);
                    writer.WriteElementString("SizeInBytes", Sequence.SubItems[6].Text);
                    writer.WriteElementString("NumberOfChannels", Sequence.SubItems[7].Text);
                }
                else
                {
                    //Write a pause to the file
                    writer.WriteElementString("SequenceName", "Pause");
                    writer.WriteElementString("TimeInSeconds", Sequence.SubItems[4].Text);
                    writer.WriteElementString("SizeInBytes", "0");
                    writer.WriteElementString("NumberOfChannels", "0");
                }

                writer.WriteEndElement(); //End the Sequence Element
            } //End writing Sequences

            writer.WriteEndElement(); //End the Show Element

            writer.Close();
        } //End Save Show

        public ListView.ListViewItemCollection OpenShowFile(string fileName)
        {
            /*
             *Open an XML Show file and parse it to a ListViewItemCollection.
             *The show data is in a ListViewItemCollection with the following order:
             *Item[0]=Sequence Name
             *Item[1]=Sequence Path
             *Item[2]=Song Title
             *Item[3]=Song Path
             *Item[4]=Time in seconds
             *Item[5]=Size in MBytes
             *Item[6]=Size in Bytes
             *Item[7]=Number of Channels
             */

            ListView tempListView = new ListView();
            string[] subItems = new string[8];
            XmlTextReader reader = new XmlTextReader(fileName);
            bool validShowFile = false;

            try
            {
                //Check to make sure it is a valid Show file
                while (reader.Read())
                {
                    if (reader.Name == "Show")
                    {
                        validShowFile = true;
                        break;
                    }
                }

                if (validShowFile)
                {
                    while (reader.Read())
                    {
                        //Read in the Sequences
                        while ((reader.NodeType == XmlNodeType.Element) & (reader.Name == "Sequence"))
                        {
                            //Clear the subItems array
                            for (int index = 0; index < 8; index++)
                            {
                                subItems[index] = "";
                            }

                            //Get the Sequence Data
                            while (reader.Read())
                            {
                                //Check for end of Sequence element
                                if ((reader.NodeType == XmlNodeType.EndElement) & (reader.Name == "Sequence"))
                                    break;

                                //Get the subItems
                                if (reader.NodeType == XmlNodeType.Element)
                                {
                                    switch (reader.Name)
                                    {
                                        case "SequenceName":
                                            reader.Read();
                                            subItems[0] = reader.Value;
                                            break;

                                        case "SequencePath":
                                            reader.Read();
                                            subItems[1] = reader.Value;
                                            break;

                                        case "SongTitle":
                                            reader.Read();
                                            subItems[2] = reader.Value;
                                            break;

                                        case "SongPath":
                                            reader.Read();
                                            subItems[3] = reader.Value;
                                            break;

                                        case "TimeInSeconds":
                                            reader.Read();
                                            subItems[4] = reader.Value;
                                            break;

                                        case "SizeInMBytes":
                                            reader.Read();
                                            subItems[5] = reader.Value;
                                            break;

                                        case "SizeInBytes":
                                            reader.Read();
                                            subItems[6] = reader.Value;
                                            break;

                                        case "NumberOfChannels":
                                            reader.Read();
                                            subItems[7] = reader.Value;
                                            break;

                                        default:
                                            break;
                                    } //End switch
                                } //End subItem
                            } //End of last subItem
                            //Add the sequence to the list view
                            ListViewItem lviItem = new ListViewItem(subItems);
                            tempListView.Items.Add(lviItem);
                        } //End of reading in a sequence 
                    } //End of file
                    //Close the file
                    reader.Close();

                    //Create a ListViewItemCollection
                    ListView.ListViewItemCollection lvicToOpen = tempListView.Items;

                    return lvicToOpen;
                } //End of a valid Show file
                //An error in reading in the Show file
                else
                {
                    MessageBox.Show("Unable to open " + fileName + "\r\rThis is not a valid Helix Show File",
                            "Helix Show Builder Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    ListView.ListViewItemCollection lvicToOpenError = tempListView.Items;

                    return lvicToOpenError;
                }
            }
            catch
            {
                //Error trying to read the XML file
                MessageBox.Show("Unable to open " + fileName + "\r\rThis is not a valid Helix Show File",
                            "Helix Show Builder Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                ListView.ListViewItemCollection lvicToOpenError = tempListView.Items;

                return lvicToOpenError;
            }
        } //End Open Show File

        #endregion Show Save/Open

        #region Playlist Save/Open

        public void SavePlaylist(ListView.ListViewItemCollection Playlist, string destinationFile)
        {
            /*
             *Save a Playlist file as an XML file.
             *The Playlist data is in a ListViewItemCollection with the following order:
             *Item[0]=Song Title
             *Item[1]=Song Path
             */

            XmlTextWriter writer = new XmlTextWriter(destinationFile, null);

            writer.Formatting = Formatting.Indented;

            //Write the header
            writer.WriteStartDocument(false);

            //Root element
            writer.WriteStartElement("Playlist");

            //Write each song to the file
            foreach (ListViewItem Sequence in Playlist)
            {
                writer.WriteStartElement("Song");
                writer.WriteElementString("Title", Sequence.SubItems[0].Text);
                writer.WriteElementString("Path", Sequence.SubItems[1].Text);
                writer.WriteEndElement(); //End the Song element
            }

            writer.WriteEndElement(); //End the Playlist element

            writer.Close();
        } // End Save Playlist

        public ListView.ListViewItemCollection OpenPlaylistFile(string fileName)
        {
            /*
             *Open an XML Show file and parse it to a ListViewItemCollection.
             *The show data is in a ListViewItemCollection with the following order:
             *Item[0]=Song Name
             *Item[1]=Song Path
             *Item[2]=Song Length
             *Item[3]=Song Bit Rate
             *Item[4]=Song Size
             */

            ListView tempListView = new ListView();
            string[] subItems = new string[2];
            XmlTextReader reader = new XmlTextReader(fileName);
            bool validPlaylistFile = false;

            try
            {
                //Check to make sure it is a valid Playlist file
                while (reader.Read())
                {
                    if (reader.Name == "Playlist")
                    {
                        validPlaylistFile = true;
                        break;
                    }
                }

                if (validPlaylistFile)
                {
                    while (reader.Read())
                    {
                        //Read in the Songs
                        while ((reader.NodeType == XmlNodeType.Element) & (reader.Name == "Song"))
                        {
                            //Clear the subItems array
                            for (int index = 0; index < subItems.Length; index++)
                            {
                                subItems[index] = "??";
                            }

                            //Get the Song Data
                            while (reader.Read())
                            {
                                //Check for end of Song element
                                if ((reader.NodeType == XmlNodeType.EndElement) & (reader.Name == "Song"))
                                    break;

                                //Get the subItems
                                if (reader.NodeType == XmlNodeType.Element)
                                {
                                    switch (reader.Name)
                                    {
                                        case "Title":
                                            reader.Read();
                                            subItems[0] = reader.Value;
                                            break;

                                        case "Path":
                                            reader.Read();
                                            subItems[1] = reader.Value;
                                            break;

                                        default:
                                            break;
                                    } //End Switch
                                } //End subItem
                            } //End of last subItem
                            //Add the song to the list view
                            ListViewItem lviItem = new ListViewItem(subItems);
                            tempListView.Items.Add(lviItem);
                        } //End of reading in a song 
                    } //End of file
                    //Close the file
                    reader.Close();

                    //Create a ListViewItemCollection
                    ListView.ListViewItemCollection lvicToOpen = tempListView.Items;

                    return lvicToOpen;
                } //End of a valid Playlist file
                //An error in reading in the Playlist file
                else
                {
                    MessageBox.Show("Unable to open " + fileName + "\r\rThis is not a valid Helix Playlist File",
                            "Helix Playlist Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    ListView.ListViewItemCollection lvicToOpenError = tempListView.Items;

                    return lvicToOpenError;
                }
            }
            catch
            {
                //Error trying to read the XML file
                MessageBox.Show("Unable to open " + fileName + "\r\rThis is not a valid Helix Playlist File",
                            "Helix Playlist Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                ListView.ListViewItemCollection lvicToOpenError = tempListView.Items;

                return lvicToOpenError;
            }
        } // End Open Playlist

        #endregion Playlist Save/Open

        #region Channel Map Save/Open

        public void SaveChannelMap(ListView.ListViewItemCollection ChannelMap, string destinationFile)
        {
            /*
             *Save a Channel Map file as an XML file.
             *The Channel Map data is in a ListViewItemCollection with the following order:
             *Item[0]="Helix System XX"
             *Item[1]="Channel Bank 1...4"
             *Item[2]=Channel Bank Function
             *Item[3]=Start Channel
             *Item[4]=End Channel
             *Item[5]=System Number
             */

            XmlTextWriter writer = new XmlTextWriter(destinationFile, null);

            writer.Formatting = Formatting.Indented;

            //Write the header
            writer.WriteStartDocument(false);

            //Root element
            writer.WriteStartElement("ChannelMap");


            //Write each Helix system to the file
            for (int index = 0; index < ChannelMap.Count; index += 4)
            {
                ListViewItem[] ChannelBank = new ListViewItem[4];

                for (int loop = 0; loop < 4; loop++)
                {
                    ChannelBank[loop] = ChannelMap[index + loop];
                }
                //Verify that they all come from the same system
                for (int loop = 0; loop < 3; loop++)
                {
                    if (ChannelBank[loop].SubItems[5].Text != ChannelBank[loop + 1].SubItems[5].Text)
                    {
                        MessageBox.Show("Error in saving the Channel Map " + loop.ToString() + " " + ChannelBank[loop].SubItems[5].Text
                            + " " + ChannelBank[loop + 1].SubItems[5].Text);
                        writer.Close();
                        return;
                    }
                }
                writer.WriteStartElement("HelixSystem");

                writer.WriteElementString("SystemNumber", ChannelBank[0].SubItems[5].Text);

                for (int loop = 0; loop < 4; loop++)
                {
                    writer.WriteStartElement("ChannelBank");
                    writer.WriteAttributeString("Number", loop.ToString());
                    writer.WriteElementString("ChBankNumber", ChannelBank[loop].SubItems[1].Text);
                    writer.WriteElementString("Function", ChannelBank[loop].SubItems[2].Text);
                    writer.WriteElementString("StartChannel", ChannelBank[loop].SubItems[3].Text);
                    writer.WriteElementString("EndChannel", ChannelBank[loop].SubItems[4].Text);
                    writer.WriteEndElement(); //End Channel Bank x
                }
                writer.WriteEndElement(); //End Helix system
            }

            writer.WriteEndElement(); //End Channel Map

            writer.Close();
        } //End Save Channel Map

        public ListView.ListViewItemCollection OpenChannelMapFile(string fileName)
        {
            /*
             *Open an XML Channel Map file and parse it to a ListViewItemCollection.
             *The Channel Map data is in a ListViewItemCollection with the following order:
             *Item[0]="Helix System XX"
             *Item[1]="Channel Bank 1...4"
             *Item[2]=Channel Bank Function
             *Item[3]=Start Channel
             *Item[4]=End Channel
             *Item[5]=System Number
             */

            ListView tempListView = new ListView();
            string[,] subItems = new string[4, 6];
            XmlTextReader reader = new XmlTextReader(fileName);
            bool validChannelMapFile = false;

            try
            {
                //Check to make sure it is a valid Playlist file
                while (reader.Read())
                {
                    if (reader.Name == "ChannelMap")
                    {
                        validChannelMapFile = true;
                        break;
                    }
                }

                if (validChannelMapFile)
                {
                    while (reader.Read())
                    {
                        //Read in the Songs
                        while ((reader.NodeType == XmlNodeType.Element) & (reader.Name == "HelixSystem"))
                        {
                            //Clear the subItems array
                            for (int index = 0; index < 6; index++)
                            {
                                subItems[0, index] = "";
                                subItems[1, index] = "";
                                subItems[2, index] = "";
                                subItems[3, index] = "";
                            }

                            //Get the Channel Map Data
                            while (reader.Read())
                            {
                                //Check for end of Helix System element
                                if ((reader.NodeType == XmlNodeType.EndElement) & (reader.Name == "HelixSystem"))
                                    break;

                                //Get the subItems
                                if (reader.NodeType == XmlNodeType.Element)
                                {
                                    switch (reader.Name)
                                    {
                                        case "SystemNumber":
                                            reader.Read();
                                            subItems[0, 5] = reader.Value;
                                            subItems[1, 5] = reader.Value;
                                            subItems[2, 5] = reader.Value;
                                            subItems[3, 5] = reader.Value;

                                            subItems[0, 0] = "Helix System " + reader.Value;
                                            subItems[1, 0] = "Helix System " + reader.Value;
                                            subItems[2, 0] = "Helix System " + reader.Value;
                                            subItems[3, 0] = "Helix System " + reader.Value;

                                            break;

                                        case "ChannelBank":
                                            int index = int.Parse(reader.GetAttribute("Number"));
                                            while (reader.Read())
                                            {
                                                if (reader.Name == "ChBankNumber")
                                                    break;
                                            }
                                            reader.Read();
                                            subItems[index, 1] = reader.Value;

                                            while (reader.Read())
                                            {
                                                if (reader.Name == "Function")
                                                    break;
                                            }
                                            reader.Read();
                                            subItems[index, 2] = reader.Value;

                                            while (reader.Read())
                                            {
                                                if (reader.Name == "StartChannel")
                                                    break;
                                            }
                                            reader.Read();
                                            subItems[index, 3] = reader.Value;

                                            while (reader.Read())
                                            {
                                                if (reader.Name == "EndChannel")
                                                    break;
                                            }
                                            reader.Read();
                                            subItems[index, 4] = reader.Value;
                                            break;

                                        default:
                                            break;
                                    } //End Switch
                                } //End subItem
                            } //End of last subItem
                            //Add the channel banks to the list view
                            for (int ChB = 0; ChB < 4; ChB++)
                            {
                                string[] tempSubItem = new string[6];

                                for (int index = 0; index < 6; index++)
                                {
                                    tempSubItem[index] = subItems[ChB, index];
                                }
                                ListViewItem lviItem = new ListViewItem(tempSubItem);
                                tempListView.Items.Add(lviItem);
                            }

                        } //End of reading in a Helix system 
                    } //End of file
                    //Close the file
                    reader.Close();

                    //Create a ListViewItemCollection
                    ListView.ListViewItemCollection lvicToOpen = tempListView.Items;

                    return lvicToOpen;
                } //End of a valid Playlist file
                //An error in reading in the Playlist file
                else
                {
                    MessageBox.Show("Unable to open " + fileName + "\r\rThis is not a valid Helix Channel Map File",
                            "Helix Channel Map Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    ListView.ListViewItemCollection lvicToOpenError = tempListView.Items;

                    return lvicToOpenError;
                }
            }
            catch
            {
                //Error trying to read the XML file
                MessageBox.Show("Unable to open " + fileName + "\r\rThis is not a valid Helix Channel Map File",
                            "Helix Channel Map Try Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                ListView.ListViewItemCollection lvicToOpenError = tempListView.Items;

                return lvicToOpenError;
            }
        } // End Open Channel Map

        #endregion Channel Map Save/Open

        #region Schedule Save/Open

        public void SaveSchedule(ListView.ListViewItemCollection Schedule,
               string channelMapPath, string destinationFile, string uploadDirPath,
               int baudRate, int panID)
        {
            /*
             *Save a Schedule file as an XML file.
             *The Schedule data is in a ListViewItemCollection with the following order:
             *Item[0]=Day Index (1=Sunday...7=Saturday)
             *Item[1]=Day
             *Item[2]=Start Time (24hr format)
             *Item[3]=End Time (24hr format)
             *Item[4]=Show Name
             *Item[5]=Show Path
             *Item[6]=Type ("S"=Show, "P"=Playlist)
            */

            XmlTextWriter writer = new XmlTextWriter(destinationFile, null);

            writer.Formatting = Formatting.Indented;

            //Write the header
            writer.WriteStartDocument(false);

            //Root element
            writer.WriteStartElement("Schedule");

            //Write each song to the file
            foreach (ListViewItem Entry in Schedule)
            {
                writer.WriteStartElement("Entry");
                writer.WriteElementString("DayIndex", Entry.SubItems[0].Text);
                writer.WriteElementString("Day", Entry.SubItems[1].Text);
                writer.WriteElementString("StartTime", Entry.SubItems[2].Text);
                writer.WriteElementString("EndTime", Entry.SubItems[3].Text);
                writer.WriteElementString("ShowName", Entry.SubItems[4].Text);
                writer.WriteElementString("ShowPath", Entry.SubItems[5].Text);
                writer.WriteElementString("Type", Entry.SubItems[6].Text);
                writer.WriteEndElement(); //End the Entry element
            }

            writer.WriteElementString("ChannelMapPath", channelMapPath);

            writer.WriteEndElement(); //End the Schedule element

            writer.Close();

            /* Open the Channel Map and read it in
             *The Channel Map data is in a ListViewItemCollection with the following order:
             *Item[0]="Helix System XX"
             *Item[1]="Channel Bank 1...4"
             *Item[2]=Channel Bank Function
             *Item[3]=Start Channel
             *Item[4]=End Channel
             *Item[5]=System Number
            */
            ListView.ListViewItemCollection ChannelMap = OpenChannelMapFile(channelMapPath);

            // Get the number of Helix Systems in the map
            int numHelixSystems = ChannelMap.Count / 4;

            // Create a directory for each Helix System and copy the firmware and calibrate files
            string saveDirName = Path.GetFileNameWithoutExtension(destinationFile);
            string saveDirPath = uploadDirPath + @"\" + saveDirName;

            if (Directory.Exists(saveDirPath))
            {
                //Delete the directory if it exists
                Directory.Delete(saveDirPath, true);
            }
            Directory.CreateDirectory(saveDirPath); //Create the new data directory

            string directoryPath;

            for (int dirLoop = 1; dirLoop <= numHelixSystems; dirLoop++)
            {
                directoryPath = saveDirPath + @"\Helix System " + dirLoop.ToString();
                Directory.CreateDirectory(directoryPath);
                int myAddress = int.Parse(ChannelMap[(dirLoop - 1) * 4].SubItems[5].Text);

                // Copy the Firmware to each directory
                string sourcePath = uploadDirPath + @"\" + "FIRMWARE.BIN";
                string destinationPath = directoryPath + @"\" + "FIRMWARE.BIN";
                File.Copy(sourcePath, destinationPath);

                // If this is the HNC then copy the calibrate files
                if (myAddress == 1)
                {
                    sourcePath = uploadDirPath + @"\" + "CALIBRAT.SEQ";
                    destinationPath = directoryPath + @"\" + "CALIBRAT.SEQ";
                    File.Copy(sourcePath, destinationPath);

                    sourcePath = uploadDirPath + @"\" + "CALIBRAT.MP3";
                    destinationPath = directoryPath + @"\" + "CALIBRAT.MP3";
                    File.Copy(sourcePath, destinationPath);
                }
            } // End creating directories and copying files

            // Create the configuration files for each system
            createConfigFiles(ChannelMap, saveDirPath, baudRate, panID);

            // Get a list of all of the shows and playlists in the schedule
            List<string> showPathList = new List<string>();
            List<string> showShortPathList = new List<string>();
            List<string> playlistPathList = new List<string>();
            List<string> playlistShortPathList = new List<string>();

            foreach (ListViewItem Entry in Schedule)
            {
                string newEntry = Entry.SubItems[5].Text; // Get the long path name
                bool inList = false;

                if (Entry.SubItems[6].Text == "S")
                {
                    // Check to see if the show is already in the list
                    for (int index = 0; index < showPathList.Count; index++)
                    {
                        if (showPathList[index] == newEntry)
                        {
                            inList = true;
                        }
                    }
                    // If not then add it to the list and get the short path name
                    if (!inList)
                    {
                        showPathList.Add(newEntry);
                        StringBuilder shortPath = new StringBuilder(255);
                        GetShortPathName(newEntry, shortPath, shortPath.Capacity);
                        showShortPathList.Add(shortPath.ToString());
                    }
                } // End if show
                else
                {
                    // Check to see if the playlist is already in the list
                    for (int index = 0; index < playlistPathList.Count; index++)
                    {
                        if (playlistPathList[index] == newEntry)
                        {
                            inList = true;
                        }
                    }
                    // If not then add it to the list and get the short path name
                    if (!inList)
                    {
                        playlistPathList.Add(newEntry);
                        StringBuilder shortPath = new StringBuilder(255);
                        GetShortPathName(newEntry, shortPath, shortPath.Capacity);
                        playlistShortPathList.Add(shortPath.ToString());
                    }
                } // End else playlist
            } // End foreach

            /* 
             *Open each show and get a list of the sequences and songs along with their short path names
             *The show data is in a ListViewItemCollection with the following order:
             *Item[0]=Sequence Name
             *Item[1]=Sequence Path
             *Item[2]=Song Title
             *Item[3]=Song Path
             *Item[4]=Time in seconds
             *Item[5]=Size in MBytes
             *Item[6]=Size in Bytes
             *Item[7]=Number of Channels
            */

            List<string> sequencePathList = new List<string>();
            List<string> sequenceShortPathList = new List<string>();
            List<string> songPathList = new List<string>();
            List<string> songShortPathList = new List<string>();

            foreach (string showPath in showPathList)
            {
                ListView.ListViewItemCollection show = OpenShowFile(showPath);

                foreach (ListViewItem sequence in show)
                {
                    // Check to see if it is a sequence and not a pause
                    if (sequence.SubItems[0].Text != "Pause")
                    {
                        string newSeq = sequence.SubItems[1].Text;
                        bool inList = false;

                        // Check to see if the sequence is already in the list
                        for (int index = 0; index < sequencePathList.Count; index++)
                        {
                            if (sequencePathList[index] == newSeq)
                            {
                                inList = true;
                            }
                        }
                        // If not then add it and get the short path also
                        if (!inList)
                        {
                            sequencePathList.Add(newSeq);
                            StringBuilder shortPath = new StringBuilder(255);
                            GetShortPathName(newSeq, shortPath, shortPath.Capacity);
                            sequenceShortPathList.Add(shortPath.ToString());
                        }

                        string newSong = sequence.SubItems[3].Text;
                        inList = false;

                        // Check to see if the song is already in the list
                        for (int index = 0; index < songPathList.Count; index++)
                        {
                            if (songPathList[index] == newSong)
                            {
                                inList = true;
                            }
                        }
                        // If not then add it and get the short path also
                        if (!inList)
                        {
                            songPathList.Add(newSong);
                            //StringBuilder shortPath = new StringBuilder(255);
                            //GetShortPathName(newSong, shortPath, shortPath.Capacity);
                            songShortPathList.Add(newSong);
                        }
                    } // End if !"Pause"
                } // End foreach sequence in show
            } // End foreach showpath

            /* 
             *Open each playlist and get a list of the songs along with their short path names
             *The playlist data is in a ListViewItemCollection with the following order:
             *Item[0]=Song Name
             *Item[1]=Song Path
             */

            foreach (string playlistPath in playlistPathList)
            {
                ListView.ListViewItemCollection playlist = OpenPlaylistFile(playlistPath);

                foreach (ListViewItem song in playlist)
                {
                    string newSong = song.SubItems[1].Text;
                    bool inList = false;

                    // Check to see if the song is already in the list
                    for (int index = 0; index < songPathList.Count; index++)
                    {
                        if (songPathList[index] == newSong)
                        {
                            inList = true;
                        }
                    }
                    // If not then add song to list and get short path name also
                    if (!inList)
                    {
                        songPathList.Add(newSong);
                        //StringBuilder shortPath = new StringBuilder(255);
                        //GetShortPathName(newSong, shortPath, shortPath.Capacity);
                        songShortPathList.Add(newSong);
                    }
                } // End foreach song
            } // End foreach playlist

            // Save a copy of each MP3 file to the Helix 1 directory
            directoryPath = saveDirPath + @"\Helix System 1\";
            for (int index = 0; index < songPathList.Count; index++)
            {
                string fileName = Path.GetFileName(songPathList[index]);
                string longFilePath = directoryPath + fileName;
                while (File.Exists(longFilePath))
                {
                    string tempFileName = Path.GetFileNameWithoutExtension(longFilePath);
                    Random rand = new Random();

                    int offset = rand.Next(10);
                    tempFileName += (offset.ToString() + ".MP3");
                    longFilePath = directoryPath + tempFileName;
                }
                File.Copy(songPathList[index], longFilePath);
                songShortPathList[index] = longFilePath;
            }

            // Now get the short file name and rename them all
            for (int index = 0; index < songShortPathList.Count; index++)
            {
                // Get the short file name for the file
                StringBuilder shortPath = new StringBuilder(255);
                GetShortPathName(songShortPathList[index], shortPath, shortPath.Capacity);

                string shortFileName = Path.GetFileName(shortPath.ToString());
                // Check to make sure it is a full 8.3 characters long
                if (shortFileName.Length < 12)
                {
                    // Add Characters to make it the full 8.3
                    string fileNameWOExtension = Path.GetFileNameWithoutExtension(shortFileName);

                    fileNameWOExtension += "~";
                    int fileNameLength = fileNameWOExtension.Length;
                    for (int cnt = 0; cnt < (8 - fileNameLength); cnt++)
                    {
                        fileNameWOExtension += cnt.ToString();
                    }

                    shortFileName = fileNameWOExtension + ".MP3";
                }
                string shortFilePath = directoryPath + shortFileName;

                // Rename the file to temp.tmp
                string tempFilePath = directoryPath + "temp.tmp";
                File.Move(songShortPathList[index], tempFilePath);

                // Now rename the file to the short file name
                File.Move(tempFilePath, shortFilePath);

                // Save the short file name
                songShortPathList[index] = shortFileName;
            }

            // Create the Sequence files for each Helix System
            for (int index = 0; index < sequencePathList.Count; index++)
            {
                string shortFileName = Path.GetFileNameWithoutExtension(sequenceShortPathList[index]);
                // Check to make sure it is a full 8 characters long
                if (shortFileName.Length < 8)
                {
                    shortFileName += "~";
                    int fileNameLength = shortFileName.Length;
                    for (int cnt = 0; cnt < (8 - fileNameLength); cnt++)
                    {
                        shortFileName += cnt.ToString();
                    }
                }
                // Add the .HLX extension
                shortFileName += ".SEQ";
                sequenceShortPathList[index] = shortFileName;

                vixenParser.saveVixenFile(sequencePathList[index], saveDirPath, shortFileName, profilePath, ChannelMap);
            }

            // Create the schedule file and save it to the Helix 1 directory
            /*
             *The Schedule data is in a ListViewItemCollection with the following order:
             *Item[0]=Day Index (1=Sunday...7=Saturday)
             *Item[1]=Day
             *Item[2]=Start Time (24hr format)
             *Item[3]=End Time (24hr format)
             *Item[4]=Show Name
             *Item[5]=Show Path
             *Item[6]=Type ("S"=Show, "P"=Playlist)
             *
             *For Each Day:
             *Day Index (1 = Sunday…7 = Saturday)
             *Number of elements for the Day (up to 9)
             *Start Time (in 24 hr format), must be in four digit format (i.e. 9:00 am would be 0900)
             *End Time
             *Type (“S” = Show, “P” = Playlist)
             *Show or Playlist File Name (8.3 format) 
            */

            int[] elementsPerDay = new int[7]; // Used to store the number of elements per day
            for (int index = 0; index < 7; index++)
            {
                elementsPerDay[index] = 0; // Set all of them to 0
            }

            // Get the number of elements for each day
            foreach (ListViewItem element in Schedule)
            {
                int day = int.Parse(element.SubItems[0].Text) - 1;
                elementsPerDay[day]++;
            }
            // Create the schedule file in the Helix 1 directory
            directoryPath = saveDirPath + @"\Helix System 1\";

            using (StreamWriter sw = File.CreateText(directoryPath + @"\SCHEDULE.SCH")) // Open the file
            {
                int index = 0;
                for (int day = 0; day < 7; day++)
                {
                    sw.WriteLine((day + 1).ToString()); // Write the day index to the file
                    sw.WriteLine(elementsPerDay[day].ToString()); // Write the number of elements per day to the file

                    for (int loop = 0; loop < elementsPerDay[day]; loop++)
                    {
                        int time = int.Parse(Schedule[index].SubItems[2].Text); // Get the start time
                        if (time < 1000)
                        {
                            sw.Write("0"); // Write the leading 0 if less than four digits
                        }
                        if (time < 100)
                        {
                            sw.Write("0");
                        }
                        if (time < 10)
                        {
                            sw.Write("0");
                        }
                        sw.WriteLine(time.ToString());

                        time = int.Parse(Schedule[index].SubItems[3].Text); // Get the end time
                        if (time < 1000)
                        {
                            sw.Write("0"); // Write the leading 0 if less than four digits
                        }
                        if (time < 100)
                        {
                            sw.Write("0");
                        }
                        if (time < 10)
                        {
                            sw.Write("0");
                        }
                        sw.WriteLine(time.ToString());

                        string type = Schedule[index].SubItems[6].Text; // Get the element type
                        sw.WriteLine(type); // Write the element type to the file

                        string elementPath = Schedule[index].SubItems[5].Text; // Get the element path
                        // Find the short file name
                        string shortElementName = "";
                        if (type == "S")
                        {
                            for (int i = 0; i < showPathList.Count; i++)
                            {
                                if (elementPath == showPathList[i])
                                {
                                    shortElementName = Path.GetFileNameWithoutExtension(showShortPathList[i]);
                                    // Make sure the file name is a full 8 characters long
                                    if (shortElementName.Length < 8)
                                    {
                                        shortElementName += "~";
                                        int fileLength = shortElementName.Length;
                                        for (int j = 0; j < (8 - fileLength); j++)
                                        {
                                            shortElementName += j.ToString();
                                        }
                                    }
                                    // Add the .SHW extension
                                    shortElementName += ".SHW";
                                    showShortPathList[i] = shortElementName;

                                    break; // break out of the for loop;
                                }
                            }
                        }
                        else
                        {
                            for (int i = 0; i < playlistPathList.Count; i++)
                            {
                                if (elementPath == playlistPathList[i])
                                {
                                    shortElementName = Path.GetFileNameWithoutExtension(playlistShortPathList[i]);
                                    // Make sure the file name is a full 8 characthers long
                                    if (shortElementName.Length < 8)
                                    {
                                        shortElementName += "~";
                                        int fileLength = shortElementName.Length;
                                        for (int j = 0; j < (8 - fileLength); j++)
                                        {
                                            shortElementName += j.ToString();
                                        }
                                    }
                                    // Add the .PLY extension
                                    shortElementName += ".PLY";
                                    playlistShortPathList[i] = shortElementName;

                                    break; // break out of the for loop;
                                }
                            }
                        }

                        sw.WriteLine(shortElementName); // Write the element name to the file
                        // Finished writing this element to the file.  Increment the index
                        index++;
                    } // End for (loop)
                } // End for (day)
                sw.Close(); // Close the Schedule file
            } // End using (Streamwriter)

            // Create the show files and save them to the Helix 1 folder
            /*
             * Helix Network Controller Show File (8.3 format .SHW)
             * Number of Items in the list (up to 99), must be in two digit format (i.e. 9 would be 09)
             * For Each Item:
             * Sequence Name (8.3 format .SEQ)
             * Song Title (8.3 format .MP3)
             * or
             * “PAUSESEC.HLX”
             * Pause Duration in Seconds, must be in four digit format (i.e. 9 would be 0009)
            */

            for (int index = 0; index < showPathList.Count; index++)
            {
                /*The show data is in a ListViewItemCollection with the following order:
                 *Item[0]=Sequence Name
                 *Item[1]=Sequence Path
                 *Item[2]=Song Title
                 *Item[3]=Song Path
                 *Item[4]=Time in seconds
                 *Item[5]=Size in MBytes
                 *Item[6]=Size in Bytes
                 *Item[7]=Number of Channels
                */
                ListView.ListViewItemCollection showFile = OpenShowFile(showPathList[index]); // Open the show file

                using (StreamWriter sw = File.CreateText(directoryPath + @"\" + showShortPathList[index])) // Open the file
                {
                    if (showFile.Count < 10)
                    {
                        sw.Write("0");
                    }
                    sw.WriteLine(showFile.Count.ToString()); // Write the number of items in show

                    foreach (ListViewItem item in showFile)
                    {
                        if (item.SubItems[0].Text == "Pause")
                        {
                            sw.WriteLine("PAUSESEC.HLX");  // Write a pause to the file
                            int duration = int.Parse(item.SubItems[4].Text); // Write the duration in four digit format
                            if (duration < 1000)
                            {
                                sw.Write("0");
                            }
                            if (duration < 100)
                            {
                                sw.Write("0");
                            }
                            if (duration < 10)
                            {
                                sw.Write("0");
                            }
                            sw.WriteLine(duration.ToString());
                        } // End if (Pause)
                        else
                        {
                            for (int i = 0; i < sequencePathList.Count; i++)
                            {
                                if (item.SubItems[1].Text == sequencePathList[i])
                                {
                                    sw.WriteLine(sequenceShortPathList[i]); // Write the sequence file name to the file
                                    break; // break out of the loop
                                }
                            }

                            for (int i = 0; i < songPathList.Count; i++)
                            {
                                if (item.SubItems[3].Text == songPathList[i])
                                {
                                    sw.WriteLine(songShortPathList[i]); // Write the song file name to the file
                                    break; // break out of the loop
                                }
                            }
                        }
                    } // End foreach (ListViewItem)

                    sw.Close(); // Close the file
                } // End using StreamWriter
            } // End for (index)

            /* Create the playlist files and save them to the Helix 1 folder
             * Helix Network Controller Playlist File (8.3 format .PLY)
             * Number of Songs in Playlist (up to 99), must be in two digit format (i.e. 9 would be 09)
             * For Each Song:
             * Song Title (8.3 format .MP3)
            */
            for (int index = 0; index < playlistPathList.Count; index++)
            {
                /* 
                 *Open each playlist and get a list of the songs along with their short path names
                 *The playlist data is in a ListViewItemCollection with the following order:
                 *Item[0]=Song Name
                 *Item[1]=Song Path
                 */
                ListView.ListViewItemCollection playlistFile = OpenPlaylistFile(playlistPathList[index]);
                //MessageBox.Show("Playlist Short Path Name:  " + playlistShortPathList[index]);

                using (StreamWriter sw = File.CreateText(directoryPath + @"\" + playlistShortPathList[index])) // Open the file
                {
                    if (playlistFile.Count < 10)
                    {
                        sw.Write("0");
                    }
                    sw.WriteLine(playlistFile.Count.ToString()); // Write the number of items in show

                    foreach (ListViewItem item in playlistFile)
                    {
                        for (int i = 0; i < songPathList.Count; i++)
                        {
                            // Find the corresponding short file name for each song
                            if (item.SubItems[1].Text == songPathList[i])
                            {
                                sw.WriteLine(songShortPathList[i]); // Write the short file name to the file
                                break; // break out of the loop
                            }
                        }
                    } // End foreach (item)
                } // End using (StreamWriter)
            } // End for (index)

            MessageBox.Show("Finished Saving Show");
        } // End Save Schedule

        public void SaveSchedule(CalendarItemCollection scheduleItems, string destinationFile)
        {
            /*
             *Save a Schedule file as an XML file.
             *The Schedule data is in a Calendar Item List with the following data:
             *Day Index (1=Sunday...7=Saturday)
             *Day (Sunday...Saturday)
             *Start Time (DateTime Format)
             *End Time (DateTime Format)
             *Item Name
             *Item Path
             *Item Type (Show, Playlist, Trigger)
            */

            XmlTextWriter writer = new XmlTextWriter(destinationFile, null);

            writer.Formatting = Formatting.Indented;

            //Write the header
            writer.WriteStartDocument(false);

            //Root element
            writer.WriteStartElement("Schedule");

            //Write each song to the file
            foreach (CalendarItem item in scheduleItems)
            {
                string dayIndex = item.StartDate.Day.ToString();
                string day = item.StartDate.DayOfWeek.ToString();

                writer.WriteStartElement("Entry");
                writer.WriteElementString("DayIndex", dayIndex);
                writer.WriteElementString("Day", day);
                writer.WriteElementString("StartTime", item.StartDate.ToString());
                writer.WriteElementString("EndTime", item.EndDate.ToString());
                writer.WriteElementString("ShowName", item.Text);
                writer.WriteElementString("ShowPath", item.ItemPath);
                writer.WriteElementString("Type", item.ItemType);
                writer.WriteEndElement(); //End the Entry element
            }

            writer.WriteEndElement(); //End the Schedule element

            writer.Close();
        }

        public ListView.ListViewItemCollection OpenScheduleFile(string fileName)
        {
            /*
             *Open a Schedule file from an XML file.
             *The Schedule data is in a ListViewItemCollection with the following order:
             *Item[0]=Day Index (1=Sunday...7=Saturday)
             *Item[1]=Day
             *Item[2]=Start Time (24hr format)
             *Item[3]=End Time (24hr format)
             *Item[4]=Show Name
             *Item[5]=Show Path
             *Item[6]=Type ("S"=Show, "P"=Playlist)
            */

            ListView tempListView = new ListView();
            string[] subItems = new string[7];
            XmlTextReader reader = new XmlTextReader(fileName);
            bool validScheduleFile = false;

            try
            {
                //Check to make sure it is a valid Show file
                while (reader.Read())
                {
                    if (reader.Name == "Schedule")
                    {
                        validScheduleFile = true;
                        break;
                    }
                }

                if (validScheduleFile)
                {
                    while (reader.Read())
                    {
                        //Read in the Sequences
                        while ((reader.NodeType == XmlNodeType.Element) & (reader.Name == "Entry"))
                        {
                            //Clear the subItems array
                            for (int index = 0; index < 7; index++)
                            {
                                subItems[index] = "";
                            }

                            //Get the Sequence Data
                            while (reader.Read())
                            {
                                //Check for end of Sequence element
                                if ((reader.NodeType == XmlNodeType.EndElement) & (reader.Name == "Entry"))
                                    break;

                                //Get the subItems
                                if (reader.NodeType == XmlNodeType.Element)
                                {
                                    switch (reader.Name)
                                    {
                                        case "DayIndex":
                                            reader.Read();
                                            subItems[0] = reader.Value;
                                            break;

                                        case "Day":
                                            reader.Read();
                                            subItems[1] = reader.Value;
                                            break;

                                        case "StartTime":
                                            reader.Read();
                                            subItems[2] = reader.Value;
                                            break;

                                        case "EndTime":
                                            reader.Read();
                                            subItems[3] = reader.Value;
                                            break;

                                        case "ShowName":
                                            reader.Read();
                                            subItems[4] = reader.Value;
                                            break;

                                        case "ShowPath":
                                            reader.Read();
                                            subItems[5] = reader.Value;
                                            break;

                                        case "Type":
                                            reader.Read();
                                            subItems[6] = reader.Value;
                                            break;

                                        default:
                                            break;
                                    } //End switch
                                } //End subItem
                            } //End of last subItem
                            //Add the sequence to the list view
                            ListViewItem lviItem = new ListViewItem(subItems);
                            tempListView.Items.Add(lviItem);
                        } //End of reading in a entry 
                        if ((reader.NodeType == XmlNodeType.Element) & (reader.Name == "ChannelMapPath"))
                        {
                            reader.Read();
                            channelMapPath = reader.Value;
                        }
                    } //End of file
                    //Close the file
                    reader.Close();

                    //Create a ListViewItemCollection
                    ListView.ListViewItemCollection lvicToOpen = tempListView.Items;

                    return lvicToOpen;
                } //End of a valid Schedule file
                //An error in reading in the Schedule file
                else
                {
                    MessageBox.Show("Unable to open " + fileName + "\r\rThis is not a valid Helix Schedule File",
                            "Helix Scheduler Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    ListView.ListViewItemCollection lvicToOpenError = tempListView.Items;

                    return lvicToOpenError;
                }
            }
            catch
            {
                //Error trying to read the XML file
                MessageBox.Show("Unable to open " + fileName + "\r\rThis is not a valid Helix Schedule File",
                            "Helix Scheduler Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                ListView.ListViewItemCollection lvicToOpenError = tempListView.Items;

                return lvicToOpenError;
            }

        } // end OpenSchedulefile

        #endregion Schedule Save/Open

        #region Configuration Files

        private void createConfigFiles(ListView.ListViewItemCollection ChannelMap, string saveDirPath, int baudRate, int panID)
        {
            int numHelixSystems = ChannelMap.Count / 4;
            string directoryPath; ;

            for (int dirLoop = 1; dirLoop <= numHelixSystems; dirLoop++)
            {
                directoryPath = saveDirPath + @"\Helix System " + dirLoop.ToString();
                int myAddress = int.Parse(ChannelMap[(dirLoop - 1) * 4].SubItems[5].Text);
                // Create a Config file for each Helix System
                string configPath = directoryPath + @"\CONFIG.HLX";
                using (StreamWriter sw = File.CreateText(configPath))
                {
                    // Write the Channel Bank details to the file
                    for (int ChBank = 0; ChBank < 4; ChBank++)
                    {
                        int ChMapIndex = (dirLoop - 1) + ChBank;

                        // Write the Channel Bank Function
                        switch (ChannelMap[ChMapIndex].SubItems[2].Text)
                        {
                            case "Helix":
                                sw.WriteLine("H");
                                break;

                            case "Renard":
                                sw.WriteLine("R");
                                break;

                            case "DMX":
                                sw.WriteLine("D");
                                break;

                            case "LEDTriks":
                                sw.WriteLine("L");
                                break;

                            default:
                                sw.WriteLine("U"); // Default to the channel bank being unused
                                break;
                        }

                        int numChannels = 0;

                        if (ChannelMap[ChMapIndex].SubItems[2].Text != "Unused")
                        {
                            // Calculate the number of channels (end channel - start channel + 1)
                            numChannels = int.Parse(ChannelMap[ChMapIndex].SubItems[4].Text);
                            numChannels -= int.Parse(ChannelMap[ChMapIndex].SubItems[3].Text);
                            numChannels++;
                        }

                        // Convert the number of channels to a three digit string
                        string formatedNumChannels = "";

                        if (numChannels < 100)
                        {
                            formatedNumChannels += "0";
                        }

                        if (numChannels < 10)
                        {
                            formatedNumChannels += "0";
                        }

                        formatedNumChannels += numChannels.ToString();

                        // Write the number of channels to the file
                        sw.WriteLine(formatedNumChannels);
                    }

                    // Write the MyAddress to the file (must be a three digit string
                    myAddress = int.Parse(ChannelMap[(dirLoop - 1) * 4].SubItems[5].Text);

                    string formatedMyAddress = "";

                    if (myAddress < 100)
                    {
                        formatedMyAddress += "0";
                    }

                    if (myAddress < 10)
                    {
                        formatedMyAddress += "0";
                    }

                    formatedMyAddress += myAddress.ToString();

                    sw.WriteLine(formatedMyAddress);

                    // Write the default XBee Baud Rate index
                    string formatedBaudRate = "";

                    switch (baudRate)
                    {
                        case 9600:
                            formatedBaudRate = "0";
                            break;

                        case 57600:
                            formatedBaudRate = "1";
                            break;

                        case 115200:
                            formatedBaudRate = "2";
                            break;

                        case 1200:
                            formatedBaudRate = "3";
                            break;

                        case 2400:
                            formatedBaudRate = "4";
                            break;

                        case 4800:
                            formatedBaudRate = "5";
                            break;

                        case 19200:
                            formatedBaudRate = "6";
                            break;

                        case 38400:
                            formatedBaudRate = "7";
                            break;

                        default:
                            formatedBaudRate = "1";
                            break;
                    }
                    sw.WriteLine(formatedBaudRate);

                    // Write the MP3 Chip Version
                    sw.WriteLine(Properties.Settings.Default.mp3ChipVer);

                    // Write the Start of the XBee Config Commands marker
                    sw.WriteLine("X");

                    // Write the number of XBee Commands
                    if (myAddress == 1)
                    {
                        sw.WriteLine("16");
                    }
                    else
                    {
                        sw.WriteLine("17");
                    }

                    // Write the Pan ID
                    sw.Write("ATID");
                    sw.WriteLine(panID.ToString("X"));

                    // Write the Baud Rate
                    sw.Write("ATBD");
                    switch (baudRate)
                    {

                        case 1200:
                            formatedBaudRate = "0";
                            break;

                        case 2400:
                            formatedBaudRate = "1";
                            break;

                        case 4800:
                            formatedBaudRate = "2";
                            break;

                        case 9600:
                            formatedBaudRate = "3";
                            break;

                        case 19200:
                            formatedBaudRate = "4";
                            break;

                        case 38400:
                            formatedBaudRate = "5";
                            break;

                        case 57600:
                            formatedBaudRate = "6";
                            break;

                        case 115200:
                            formatedBaudRate = "7";
                            break;

                        default:
                            formatedBaudRate = "6";
                            break;
                    }
                    sw.WriteLine(formatedBaudRate);

                    // Write the Address
                    sw.Write("ATMY");
                    sw.WriteLine(myAddress.ToString("X"));

                    // The next several commands are unique between the HNC and HNNs

                    if (myAddress == 1)
                    {
                        // HNC Settings
                        // Write the Destination Address Low
                        sw.WriteLine("ATDLFFFF"); // Broadcast address

                        // Write the Destination Address High
                        sw.WriteLine("ATDH0");

                        // Write the Network Coordinator
                        sw.WriteLine("ATCE1");

                        // Write the Network Coordinator Settings
                        sw.WriteLine("ATA26");
                    }
                    else
                    {
                        // HNN Settings
                        // Write the Destination Address Low
                        sw.WriteLine("ATDL1"); // HNC address

                        // Write Destination Address High
                        sw.WriteLine("ATDH0");

                        // Write the Network End Device
                        sw.WriteLine("ATCE0");

                        // Write the Network End Device Settings
                        sw.WriteLine("ATA16");

                        // Force the End Device to disassociate
                        sw.WriteLine("ATDA");
                    }

                    // Write Streaming Data
                    sw.WriteLine("ATRO0");

                    // Write 802.15.4 (no ACKs) mode
                    sw.WriteLine("ATMM1");

                    // Write Max Power Level
                    sw.WriteLine("ATPL4");

                    // Write Pin 15 to be AI
                    sw.WriteLine("ATD51");

                    // Write Pin 6 to be RSSI
                    sw.WriteLine("ATP01");

                    // Write RSSI timer to 500ms
                    sw.WriteLine("ATRP5");

                    // Write Command Mode Timeout to 1.5 seconds
                    sw.WriteLine("ATCT000F");

                    // Write the settings to NVRAM
                    sw.WriteLine("ATWR");

                    // Exit Command Mode
                    sw.WriteLine("ATCN");

                    sw.Close();
                } // End Writing the Config File
            } // End For Loop
        }

        #endregion Configuration Files

        #region Not Sure Still Needed

        public void SaveShowMode1(ListView.ListViewItemCollection lvicToBeSaved,
        string destinationFile, DateTime showStartTime, DateTime showEndTime, int maxNumChannels)
        {
            /*  Save a Mode 1 Show.  This will create a showfile.hlx with the start and stop times
            *  the total number of sequences and pauses in the show, and an ordered list of all of the 
            *  sequence names and song names.
            *  It then reformats the Vixen files to the Helix format and stores them in directories.*/

            int count = lvicToBeSaved.Count;
            int progressStep = 100 / count;

            StatusForm status = new StatusForm();

            status.UpdateStatusTitle("Saving Helix Show");
            status.UpdateStatusLabel("Creating Show File");
            status.Show();

            using (StreamWriter sw = File.CreateText(destinationFile))
            {
                //Create the show builder file.  Save all of the items
                //in the seqListView to the show builder file.

                sw.WriteLine("Valid Helix Show Builder File"); //Write the header to the file
                sw.WriteLine(count.ToString()); //Write the number of rows to the file

                foreach (ListViewItem lvi in lvicToBeSaved)
                {
                    //Write the data to the file
                    ListViewItem.ListViewSubItemCollection subItems = lvi.SubItems;
                    for (int subItemIndex = 0; subItemIndex < 8; subItemIndex++)
                    {
                        sw.WriteLine(subItems[subItemIndex].Text); //Write the subItems to the file
                    }
                }
                sw.Close(); //Close the show builder file
            }

            status.Close();
            MessageBox.Show("The Helix Show has been saved");
            //}
        }

        public void SaveShowMode3(ListView.ListViewItemCollection lvicToBeSaved, string destinationFile,
            int chOffset, int numCh, int maxNumChannels)
        {
            /*  Save a Mode 3 Show.  It reformats the Vixen sequence files into Helix format and stores them
             *  in a directory.  It creates one directory for each Helix system (each 128 channels).
             *  lvicToBeSaved is the list of sequences to reformat
             *  destinationFile is the path to where the new files are to be stored
             *  chOffset is the first channel in the sequence that needs to be controlled by the Helix
             *  numCh is the number of channels to be controlled by the Helix
             *  maxNumChannels is the total number of channels in the sequence
             */

            int count = lvicToBeSaved.Count;
            int progressStep = 100 / count;

            StatusForm status = new StatusForm();

            status.UpdateStatusTitle("Saving Helix Show");
            status.UpdateStatusLabel("Creating Show File");
            status.Show();

            using (StreamWriter sw = File.CreateText(destinationFile))
            {
                //Create the show builder file.  Save all of the items
                //in the seqListView to the show builder file.
                //This is the file that the Network Supervisor needs to be able
                //edit this show in the future

                sw.WriteLine("Valid Helix Show Builder File"); //Write the header to the file
                sw.WriteLine(count.ToString()); //Write the number of rows to the file

                foreach (ListViewItem lvi in lvicToBeSaved)
                {
                    //Write the data to the file
                    ListViewItem.ListViewSubItemCollection subItems = lvi.SubItems;
                    for (int subItemIndex = 0; subItemIndex < 8; subItemIndex++)
                    {
                        sw.WriteLine(subItems[subItemIndex].Text); //Write the subItems to the file
                    }
                }
                sw.Close(); //Close the show builder file
            }

            status.UpdateStatusLabel("Creating the Directories");

            string destinationPath = Path.GetDirectoryName(destinationFile);
            string newDirectoryName = Path.GetFileNameWithoutExtension(destinationFile);
            destinationPath += @"\" + newDirectoryName;  //Create the path to the data directory

            if (Directory.Exists(destinationPath))
            {
                //Delete the directory if it exists
                Directory.Delete(destinationPath, true);
            }
            Directory.CreateDirectory(destinationPath); //Create the new data directory

            int numDirectories = numCh / 128; //Calculate the number of directories needed

            if (numDirectories * 128 != numCh) //Handle the situation when only a partial Helix is used
            {
                numDirectories++;
            }

            /*seqListView SubItems
             * 0:  Vixen File Name or "Pause"
             * 1:  Complete Path to Vixen File
             * 2:  Song Title
             * 3:  Complete Path to Song
             * 4:  Time in Seconds of the Sequence
             * 5:  Formated Size of the Item in MB
             * 6:  Size of the Item in B
             * 7:  Number of Channels in Sequence
            */

            int dirLoop;
            string directoryPath;

            for (dirLoop = 1; dirLoop <= numDirectories; dirLoop++) //Create the subdirectories
            {
                directoryPath = destinationPath + @"\Helix System " + dirLoop.ToString();
                Directory.CreateDirectory(directoryPath);
            }

            status.UpdateStatusLabel("Creating the Sequence Files");

            foreach (ListViewItem lvi in lvicToBeSaved)
            {
                ListViewItem.ListViewSubItemCollection subItems = lvi.SubItems;

                if (subItems[0].Text != "Pause")
                {

                    //Convert the sequence file name to a standard 8.3 format
                    string fileName = subItems[1].Text;

                    StringBuilder shortPath = new StringBuilder(255);
                    GetShortPathName(fileName, shortPath, shortPath.Capacity);

                    string updatedShortPath = Path.ChangeExtension(shortPath.ToString(), ".HLX");

                    string vixenFileName = Path.GetFileName(updatedShortPath);


                    int channelOffset = chOffset;
                    int numChannels;

                    vixenParser.ParseVixenFile(subItems[1].Text, maxNumChannels);

                    int numChannelsLeft = numCh;

                    for (dirLoop = 1; dirLoop <= numDirectories; dirLoop++)
                    {
                        //channelOffset += 128;
                        directoryPath = destinationPath + @"\Helix System " + dirLoop.ToString();
                        directoryPath += @"\" + vixenFileName;
                        if (numChannelsLeft > 128)
                        {
                            numChannels = 128;
                        }
                        else
                        {
                            numChannels = numChannelsLeft;
                        }
                        vixenParser.saveOutputFileMode3(directoryPath, channelOffset, numChannels, maxNumChannels);
                        numChannelsLeft -= numChannels;
                        channelOffset += 128;
                    }

                    status.UpdateProgressBar(progressStep);
                }
                status.Close();
                MessageBox.Show("The Helix Show has been saved");
                //}
            }
        }


        public string Bytes2MegaBytes(long length)
        {
            string numMegaBytes = "";

            if (length < 1048576)
            {
                length *= 100;
                long formatedLength = length / (1048576);

                numMegaBytes = "0.";
                if (formatedLength < 10)
                {
                    numMegaBytes += "0" + formatedLength.ToString() + " MB";
                }
                else
                {
                    numMegaBytes += formatedLength.ToString() + " MB";
                }
            }
            else
            {
                long formatedLength = length / 1048576;

                length -= (formatedLength * 1048576);

                numMegaBytes = formatedLength.ToString() + ".";

                length *= 100;
                formatedLength = length / 1048576;
                if (formatedLength < 10)
                {
                    numMegaBytes += "0" + formatedLength.ToString() + " MB";
                }
                else
                {
                    numMegaBytes += formatedLength.ToString() + " MB";
                }
            }

            return numMegaBytes;
        }

        #endregion Not Sure Still Needed
    }
}
